-
Notifications
You must be signed in to change notification settings - Fork 355
HTTP/2: per-stream idle timeout #581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
At the moment we only expose connection-level timeouts (for example via IOReactorConfig socket and session timeouts); there is no existing notion of per-stream timeout in the HTTP/2 code. |
What about |
RequestConfig#setResponseTimeout IMO lives in the client API, while H2Config is a transport-level setting in Core. I would keep this change scoped to Core and then look at wiring responseTimeout onto an appropriate per-stream timeout in the httpclient5 layer as a follow-up |
|
@arturobernalg @rschmitt This timeout value / these timeout values must be settable / mutable at runtime exactly the same way as Socket read timeout. Just setting an initial value from a config bean is not good enough. At the client level the request execution pipeline could use that API to apply |
@ok2c Makes sense. I can treat the timeouts in H2Config as defaults and keep the actual per-stream timeout state on H2Stream. |
@arturobernalg I agree with @rschmitt that is the wrong place for timeout settings. Those are meant to be H2 protocol related configs. Please use connection socket timeout as an initial / default value. |
2f5d095 to
31bbf5b
Compare
|
|
I'd like to see HTTP/2 test coverage added to |
@rschmitt That is fair, but the feature would need to have been made available in an alpha release of core or the timeout tests would need to be ported to core. |
@rschmitt I’ve added an async core HTTP/2 socket-timeout test in httpcore5-testing ( |
|
@arturobernalg Please rebase this change-set off the latest master and I will review it |
c6364c8 to
d7b8e8b
Compare
@ok2c please take a look |
b60f8b0 to
ccf73f8
Compare
Ideally I'd like to see contract testing, i.e. the same test cases running for HTTP, HTTPS, h2, and h2c. This ensures that the high-level API behaves consistently across the various implementations; it's also a very effective way of asserting that the various config options are being propagated and applied correctly throughout the client's internals. This is most effectively done through tests in |
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2StreamTimeoutException.java
Outdated
Show resolved
Hide resolved
|
@arturobernalg Please try to minimize changes to H2 protocol code. More functionality can be added incrementally at a later point. Try to keep it small and lean. |
084cab8 to
5cd4675
Compare
@ok2c please another pass |
ee03f78 to
e627911
Compare
|
@arturobernalg Better, but please look at all my comments |
8534aa0 to
8cf5233
Compare
|
@arturobernalg Please re-open and rebase this change-set off the latest master. This is presently more important than other open pull requests in core |
8cf5233 to
127a32f
Compare
@ok2c done |
...ore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/CancellableExecution.java
Outdated
Show resolved
Hide resolved
978dfae to
ce72c8c
Compare
Expose configuration via H2Config, throw H2StreamTimeoutException on expiry and keep the connection alive Extend test coverage and add an example client demonstrating timed-out and successful streams
ce72c8c to
a500259
Compare
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java
Outdated
Show resolved
Hide resolved
httpcore5/src/main/java/org/apache/hc/core5/reactor/IOSessionImpl.java
Outdated
Show resolved
Hide resolved
db30dd0 to
ddbdcb0
Compare
9b09204 to
0078239
Compare
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2StreamTimeoutClientExample.java
Outdated
Show resolved
Hide resolved
2036b6d to
7b11325
Compare
ok2c
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arturobernalg Almost there.
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2StreamTimeoutException.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Show resolved
Hide resolved
3d28c0e to
d3008c2
Compare
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2StreamTimeoutException.java
Outdated
Show resolved
Hide resolved
37287aa to
c626e45
Compare
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2Stream.java
Outdated
Show resolved
Hide resolved
| .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext())) | ||
| .setIOReactorConfig( | ||
| IOReactorConfig.custom() | ||
| .setSoTimeout(Timeout.ofSeconds(30)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also ConnectionConfig#setSocketConfig and RequestConfig#setResponseTimeout. Will those config values also get threaded into this implementation, the way they are in HTTP/1.1? (Note the precedence rules: ConnectionConfig overrides SocketConfig, and responseTimeout overrides socket timeouts.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rschmitt Once this feature has been made available in client, client level configs will be used to set the idle timeout value for H2 streams.
| * | ||
| * @since 5.5 | ||
| */ | ||
| public class H2StreamTimeoutException extends InterruptedIOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason not to just subclass or reuse java.net.SocketTimeoutException?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rschmitt But this exception does not represent a socket timeout. It is a different timeout by origin and as such it extends InterruptedIOException but not SocketTimeoutException. This enables the caller to differentiate socket timeouts that affect the entire connection and all its H2 streams from an individual H2 stream timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that's reasonable
| // not supported | ||
| this.idleTimeout = timeout; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is so satisfying to see! I think this is the ideal outcome: zero API changes (except for the new exception type), backfilling missing support for existing APIs, improving consistency across protocols, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rschmitt Unfortunately this is not quite the case. I was unable to articulate to @arturobernalg exactly what API changes I wanted, so I ended up implementing them in a separate commit.
833cd2a to
3d532a2
Compare
; Handle cancelled SelectionKey in interestOps access
a697f1b to
becade0
Compare
This change introduces per-stream idle and lifetime timeouts enforced by the HTTP/2 core multiplexer. Streams that exceed the configured limits are reset with H2StreamTimeoutException, while the underlying HTTP/2 connection remains usable for other streams.
Configuration is exposed via H2Config.setStreamIdleTimeout and setStreamLifetimeTimeout and is disabled by default, so existing users see no behaviour change unless they opt in. H2Stream now tracks creation and last-activity timestamps, and AbstractH2StreamMultiplexer inspects those on I/O events to apply the timeouts without background threads.